package com.android.webserver.fwapi;


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import android.content.Context;
import android.net.UrlQuerySanitizer.ValueSanitizer;
import android.util.Log;

public abstract class WebPage
{
	protected Request					request;
	private ArrayList<String>	responseHeadersList;
	protected byte[]					response_contentByteArray	= null;
	protected Context					context;
	protected boolean					isHTML;
	private ArrayList<Cookie>	cookies;
	private int								HTTPStatusCode						= HttpURLConnection.HTTP_ACCEPTED;

	protected abstract boolean create(Object... objects);

	protected abstract void finish();

	/**
	 * Return a POST query parameter
	 * @param parameter Parameter name
	 * @return Parameter value, null if the parameter is not in the request.
	 */
	protected String getPOSTParameter(String parameter)
	{
		if (request.getType() == Request.GET_REQUEST)
			return null;
		return request.getParameter(parameter);
	}

	/**
	 * Return a GET query parameter
	 * @param parameter Parameter name
	 * @return Parameter value, null if the parameter is not in the request.
	 */
	protected String getGETParameter(String parameter)
	{
		if (request.getType() == Request.POST_REQUEST)
			return null;

		return request.getParameter(parameter);
	}
	
	/**
	 * Return a POST query parameter
	 * @param parameter Parameter name
	 * @param valueSanitizer Choose which characters should be escaped (See URLQuerySanitizer)
	 * @return Parameter value, null if the parameter is not in the request.
	 */
	protected String getPOSTParameter(String parameter, ValueSanitizer valueSanitizer)
	{
		if (request.getType() == Request.GET_REQUEST)
			return null;

		return request.getParameter(parameter, valueSanitizer);
	}
	
	/**
	 * Return a GET query parameter
	 * @param parameter Parameter name
	 * @param valueSanitizer Choose which characters should be escaped (See URLQuerySanitizer)
	 * @return Parameter value, null if the parameter is not in the request.
	 */
	protected String getGETParameter(String parameter, ValueSanitizer valueSanitizer)
	{
		if (request.getType() == Request.POST_REQUEST)
			return null;

		return request.getParameter(parameter, valueSanitizer);
	}
	
	/**
	 * Set the response HTTP status code. by default : HttpURLConnection.HTTP_ACCEPTED
	 * @param code HTTP status code.
	 */
	protected void setHTTPStatusCode(int code)
	{
		
		HTTPStatusCode = code;
	}

	/**
	 * Set a cookie. By default : the cookie path is set to the request URL; the httpOnly flag = true; 
	 * @param name Cookie name
	 * @param value Cookie value
	 */
	protected void setCookie(String name, String value)
	{
		try
		{
			cookies.add(new Cookie(new URL(request.getURI()), name, value));
		}
		catch (MalformedURLException e)
		{
			Log.e("WebServer", "WebPage:setCookie : " + e);
		}
	}

	/** Set a cookie.
	 * @param name cookie name
	 * @param value cookie value
	 * @param expire expiration date (Max-Age)
	 * @param path cookie path (if null, set to request URL)
	 * @param domain cookie domain (if null, set to request domain)
	 * @param secure (secure flag, if null and https enabled, secure flag is set to true)
	 * @param httpOnly If true, this cookie will not be accessible by JavaScript. By default : true
	 */
	protected void setCookie(String name, String value, Integer expire,
			String path, String domain, Boolean secure, Boolean httpOnly)
	{
		try
		{
			Cookie c = new Cookie(new URL(request.getURI()), name, value);
			if (expire != null)
				c.setExpires(expire.toString());
			if (path != null)
				c.setPath(path);
			if (domain != null)
				c.setDomain(domain);
			if (secure != null)
				c.setSecure(secure);
			if (httpOnly != null)
				c.setHttpOnly(httpOnly);
			cookies.add(c);
		}
		catch (MalformedURLException e)
		{
			Log.e("WebServer", "WebPage:setCookie : " + e);
		}
	}

	/**
	 * Add a header to the HTTP response
	 * @param header Full header line without end of line (example : "Content-type : text/plain")
	 */
	public void header(String header)
	{
		responseHeadersList.add(header);
	}

	protected WebPage(Context context, Request request)
	{
		this.context = context;
		this.request = request;
		responseHeadersList = new ArrayList<String>();
		isHTML = false;
		cookies = new ArrayList<Cookie>();
	}

	protected final String getContent()
	{
		if (response_contentByteArray == null)
			response_contentByteArray = new byte[] {};
		if (isHTML)
			return new String(response_contentByteArray);
		else
			return Base64.encodeBytes(response_contentByteArray);
	}

	/**
	 * Serialize and base64 encode the headers list.
	 * @return Base64 encoded headers list.
	 */
	protected final String getHeaders()
	{
		if (HTTPStatusCode == HttpURLConnection.HTTP_ACCEPTED)
			for (int i = 0; i < cookies.size(); i++)
				responseHeadersList.add("Set-Cookie: " + cookies.get(i).toString() );
		
		try
		{
			ByteArrayOutputStream out_ = new ByteArrayOutputStream();
			ObjectOutputStream out;
			out = new ObjectOutputStream(out_);
			out.writeObject(responseHeadersList);
	    out.close();
	    return Base64.encodeBytes(out_.toByteArray());
		}
		catch (IOException e)
		{
				Log.e("WebServer", "WebPage:getHeaders : cannot serialize headers");
				return null;
		}
	}

	/**
	 * Getter
	 * @return Return the response HTTP status code
	 */
	int getHTTPStatusCode()
	{
		return HTTPStatusCode;
	}
}